package com.vercer.engine.proxy;

import java.util.concurrent.Future;
import java.util.logging.Logger;

import com.google.appengine.api.quota.QuotaService;
import com.google.appengine.api.quota.QuotaServiceFactory;
import com.google.apphosting.api.ApiProxy.ApiConfig;
import com.google.apphosting.api.ApiProxy.ApiProxyException;
import com.google.apphosting.api.ApiProxy.Delegate;
import com.google.apphosting.api.ApiProxy.Environment;

public class LoggingApiProxyDelegate extends DelegatingApiProxy
{
	private static final Logger log = Logger.getLogger(LoggingApiProxyDelegate.class.getName());
	private QuotaService quotaService;

	public LoggingApiProxyDelegate(Delegate<Environment> delegate)
	{
		super(delegate);
		quotaService = QuotaServiceFactory.getQuotaService();
	}

	@Override
	public byte[] makeSyncCall(Environment arg0, String arg1, String arg2, byte[] arg3)
			throws ApiProxyException
	{
		long startApiTimeInMegaCycles = quotaService.getApiTimeInMegaCycles();
		long startCpuTimeInMegaCycles = quotaService.getCpuTimeInMegaCycles();
		
		byte[] result = super.makeSyncCall(arg0, arg1, arg2, arg3);
		
		long endApiTimeInMegaCycles = quotaService.getApiTimeInMegaCycles();
		long endCpuTimeInMegaCycles = quotaService.getCpuTimeInMegaCycles();
		
		int apiMs = (int) Math.round(quotaService.convertMegacyclesToCpuSeconds(endApiTimeInMegaCycles - startApiTimeInMegaCycles) * 1000);
		int cpuMs = (int) Math.round(quotaService.convertMegacyclesToCpuSeconds(endCpuTimeInMegaCycles - startCpuTimeInMegaCycles) * 1000);
		
		log.info(arg1 + " " + arg2 + " cpu_ms=" + cpuMs + " api_ms=" + apiMs + ": " + restrictLength(new String(arg3)));
		
		return result;
	}

	@Override
	public Future<byte[]> makeAsyncCall(Environment arg0, String arg1, String arg2, byte[] arg3,
			ApiConfig arg4)
	{
		long startApiTimeInMegaCycles = quotaService.getApiTimeInMegaCycles();
		long startCpuTimeInMegaCycles = quotaService.getCpuTimeInMegaCycles();
		
		Future<byte[]> result = super.makeAsyncCall(arg0, arg1, arg2, arg3, arg4);
		
		long endApiTimeInMegaCycles = quotaService.getApiTimeInMegaCycles();
		long endCpuTimeInMegaCycles = quotaService.getCpuTimeInMegaCycles();
		
		int apiMs = (int) Math.round(quotaService.convertMegacyclesToCpuSeconds(endApiTimeInMegaCycles - startApiTimeInMegaCycles) * 1000);
		int cpuMs = (int) Math.round(quotaService.convertMegacyclesToCpuSeconds(endCpuTimeInMegaCycles - startCpuTimeInMegaCycles) * 1000);
		
		log.info(arg1 + " " + arg2 + " cpu_ms=" + cpuMs + " api_ms=" + apiMs + ": " + restrictLength(new String(arg3)));
		
		return result;
	}

	private String restrictLength(String string)
	{
		return string.length() < 100 ? string : string.substring(0, 100) + "...";
	}
}
